package com.xzzz.irda.auth.server.authentication;

import cn.hutool.core.util.StrUtil;
import com.xzzz.irda.auth.core.authorization.Authorization;
import com.xzzz.irda.auth.core.authorization.AuthorizationWx;
import com.xzzz.irda.auth.core.constants.GrantTypeEnum;
import com.xzzz.irda.auth.core.exception.AuthException;
import com.xzzz.irda.auth.core.exception.AuthRCode;
import com.xzzz.irda.auth.core.AuthBaseProperties;
import com.xzzz.irda.auth.server.AuthServerConfiguration;
import com.xzzz.irda.auth.server.pojo.LoginMetadata;
import com.xzzz.irda.auth.server.service.UserDetail;
import com.xzzz.irda.auth.server.service.UserDetailService;
import lombok.extern.slf4j.Slf4j;
import org.springframework.beans.factory.annotation.Autowired;

import java.util.List;

/**
 * @author wangyf
 * 
 */
@Slf4j
public class AuthenticationWxOpenIdManager extends AbstractAuthenticationManager {

    @Autowired
    private UserDetailService userDetailService;

    /**
     * 用于构造抽象类中的授权配置和配置文件
     *
     * @param authServerConfiguration         服务端配置
     * @param authBaseProperties 配置文件
     */
    public AuthenticationWxOpenIdManager(
            AuthServerConfiguration authServerConfiguration,
            AuthBaseProperties authBaseProperties) {
        super(authServerConfiguration, authBaseProperties);
    }

    /**
     * 该类的授权类型, 策略类初始化时的类型判断
     *
     * @return 授权类型
     * @see AuthenticationManagerStrategy#AuthenticationManagerStrategy(List)
     */
    @Override
    public String getGrantType() {
        return GrantTypeEnum.WECHAT.getType();
    }


    /**
     * 授权对象的业务数据补充
     *
     * @param authorization 授权对象
     * @param login         请求参数
     * @return 授权主体
     */
    @Override
    public Authorization authorizationBeforeProcess(Authorization authorization, LoginMetadata login) {
        AuthorizationWx authorizationWx = (AuthorizationWx) authorization;
        if (StrUtil.isBlank(login.getOpenId())) {
            throw new AuthException(AuthRCode.WECHAT_LOGIN_FAULT.getCode(), "OPENID不得为空");
        }
        authorizationWx.setOpenId(login.getOpenId());
        return authorizationWx;
    }

    /**
     * 处理内部登录方式的授权主体, 主体中包含用户名
     * 生成 token, 不同的授权类型获取用户的方式不同, 此处需要重写 token 生成方式
     *
     * @param authorization 授权主体
     * @return 返回 token
     */
    @Override
    public UserDetail findUser(Authorization authorization, LoginMetadata login) {
        AuthorizationWx authorizationWx = (AuthorizationWx) authorization;
        UserDetail userDetail = userDetailService.loadUserByWxOpenId(authorizationWx.getOpenId());
        if (userDetail == null) {
            throw new AuthException(AuthRCode.USER_NOT_EXIST);
        }
        return userDetail;
    }

}
